package org.springframework.aop.aspectj;

import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * @Name AspectJExpressionPointcut
 * @Description: 切点表达式的 AspectJ [实现] 类
 * @Version v1.0.0
 * @Author: lichao
 * @Date: 2024-03-27 14:51:53
 **/
public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher {
    // 支持的切点表达式集合
    private static final Set<PointcutPrimitive> SUPPORT_PRIMITIVES = new HashSet<>();

    static {
        SUPPORT_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
    }

    private final PointcutExpression pointcutExpression;

    public AspectJExpressionPointcut(String pointcutExpression) {
        // 1. 获取切点表达达解析器
        PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(SUPPORT_PRIMITIVES, this.getClass().getClassLoader());
        // 2. 解析切点表达式
        this.pointcutExpression = pointcutParser.parsePointcutExpression(pointcutExpression);
    }

    @Override
    public boolean filter(Class<?> clazz) {
        return pointcutExpression.couldMatchJoinPointsInType(clazz);
    }

    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        return pointcutExpression.matchesMethodExecution(method).alwaysMatches();
    }

    @Override
    public ClassFilter getClassFilter() {
        return this;
    }

    @Override
    public MethodMatcher getMethodMatcher() {
        return this;
    }
}

